package com.translate.web.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.translate.web.constant.RedisConstant;
import com.translate.web.dao.DepartmentMapper;
import com.translate.entity.Department;
import com.translate.entity.User;
import com.page.PageResponseData;
import com.translate.web.service.IDepartmentService;
import com.basic.service.impl.BaseServiceImpl;
import com.translate.vo.contract.IDepartmentVO;


@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements IDepartmentService {

	public DepartmentServiceImpl(DepartmentMapper mapper) {
		super(mapper);
		// TODO Auto-generated constructor stub
	}

	private RedisTemplate<String, Object> redisTemplate;


	@Autowired
	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}


	@Override
	protected Department getEntityInstance() {
		// TODO Auto-generated method stub
		return super.getEntityInstance();
	}


	@Override
	protected Class<Department> getEntityClass() {
		// TODO Auto-generated method stub
		return super.getEntityClass();
	}


	@Override
	protected void insertPropteris(Department data) {
		
		long time = System.currentTimeMillis() / 1000;
		
		data.setCreateTime(time);
		
		data.setUpdateTime(time);
	}


	@Override
	protected void updatePropteris(Department data) {
		// TODO Auto-generated method stub
		data.setUpdateTime(System.currentTimeMillis() / 1000);
	}
	
	/**
	 * 
	 * @return
	 */
	public List<Department> getDepartments() {
		
		DepartmentMapper departmentMapper = this.getBaseMapper();
		
		return departmentMapper.getDepartments();
		
	}
	
	public List<Department> getDepartmentsCache() {
		String key = RedisConstant.getDepartmentKey();
		
		ValueOperations<String, Object> valueOperations = this.redisTemplate.opsForValue();
		
		List<Department> departments = (List<Department>) valueOperations.get(key);
		
		if (null != departments) {
			return departments;
		}
		
		DepartmentMapper departmentMapper = this.getBaseMapper();
		
		departments = departmentMapper.getDepartments();
		
		if (null == departments) {
			departments = new ArrayList<>(0);
			valueOperations.set(key, departments, 3, TimeUnit.SECONDS);
			
			return departments;
		}
		
		valueOperations.set(key, departments, 20, TimeUnit.SECONDS);

		return departments;
	}
	
	public List<Department> getTopDepartmentsCache() {
		String key = RedisConstant.getTopDepartmentKey();
		
		ValueOperations<String, Object> valueOperations = this.redisTemplate.opsForValue();
		
		List<Department> departments = (List<Department>) valueOperations.get(key);
		
		if (null != departments) {
			return departments;
		}
		
		DepartmentMapper departmentMapper = this.getBaseMapper();
		
		departments = departmentMapper.getTopDepartments();
		
		if (null == departments) {
			departments = new ArrayList<>(0);
			valueOperations.set(key, departments, 3, TimeUnit.SECONDS);
			
			return departments;
		}
		
		valueOperations.set(key, departments, 20, TimeUnit.SECONDS);

		return departments;
	}


	@Override
	public <VO extends IDepartmentVO> List<VO> getDepartmentsToCache(Class<VO> target) {

		List<VO> vos = new ArrayList<>();
		
		List<Department> departments =  getDepartmentsCache();
		
		VO vo;
		
		try {
		for (Department department : departments) {
			
			vo = target.newInstance();
			
			buildVO(vo, department);
			
			vos.add(vo);
			
		}} catch (Exception e) {
			throw new Error(e);
		}
		
		return vos;
		
	}

	protected <VO extends IDepartmentVO> void buildVO(VO vo, Department department) {
		
		vo.setId(department.getId());
		
		vo.setName(department.getName());
		
		vo.setNum(department.getNum());
		
		vo.setpId(department.getpId());
		
		vo.setRemark(department.getRemark());
	}
	

	@Override
	public Department getDepartmentCache(int departmentId) {
		
		String key = RedisConstant.getDepartmentByIdKey(departmentId);
		
		ValueOperations<String, Object> valueOperations = this.redisTemplate.opsForValue();
		
		Department department = (Department) valueOperations.get(key);
		
		if (null != department) {
			return department;
		}
		
		department = this.selectByPrimaryKey(departmentId);
		
		if (null == department) {
			
			department = new Department();
			
			valueOperations.set(key, department, 3, TimeUnit.SECONDS);
			
			return department;
		}
		
		valueOperations.set(key, department, 10, TimeUnit.SECONDS);
		
		return department;
		
	}


	@Override
	public <VO extends IDepartmentVO> List<VO> getTopDepartmentsToCache(Class<VO> target) {
		
		List<VO> vos = new ArrayList<>();
		
		List<Department> departments =  getTopDepartmentsCache();
		
		VO vo;
		
		try {
		for (Department department : departments) {
			
			vo = target.newInstance();
			
			buildVO(vo, department);
			
			vos.add(vo);
			
		}} catch (Exception e) {
			throw new Error(e);
		}
		
		return vos;
	}
	
}
